from sqlalchemy import or_

from server import db, api_auth, user_opt, app_auth
from flask import jsonify, Blueprint, request, g
from server.model.order import Order, create_wechat_order, OrderStatus, get_total_fee
from server.model import set_field, query_by_field
import math

a_order = Blueprint('app/order', __name__)
exclude_data = {'order_no', 'actual_paid', 'security_code', 'user_id', 'express_status'}


@a_order.route('', methods=['GET'])
@app_auth.login_required
def get_orders():
    """
                    @@@
                    #### Args:
                           {
                                page: 1,
                                limit: 20,
                                filter: {},
                                start_time: "2021-09-10",
                                end_time: "2021-09-12",
                            }
                    #### Returns::
                            {
                                'code': 20000,
                                'items': [u.to_dict() for u in order_list],
                            }
                """
    page = request.args.get('page', type=int, default=1)
    limit = request.args.get('limit', type=int, default=20)
    start_time = request.args.get('start_time')
    end_time = request.args.get('end_time')
    query_filter = request.args.get('filter')

    try:

        # order_list = Order.query.filter(Order.user_id == g.user.id, Order.pay_status == OrderStatus.Paid)
        order_list = Order.query.filter(
            Order.user_id == g.user.id,
            or_(Order.pay_status == OrderStatus.Paid, Order.pay_status == OrderStatus.RefundSucceed, Order.pay_status == OrderStatus.Not)
        )

        if query_filter:
            order_list = query_by_field(order_list, query_filter, Order)

        if start_time:
            order_list = order_list.filter(db.cast(Order.create_time, db.Date) >= start_time)

        if end_time:
            order_list = order_list.filter(db.cast(Order.create_time, db.Date) <= end_time)
        total = order_list.count()

        order_list = order_list.order_by(Order.create_time.desc()).offset((page - 1) * limit).limit(limit).all()

        # 在返回数据之前，添加isRefund字段到每个订单字典中
        return jsonify({
            'code': 20000,
            'message': 'success',
            'items': [u.to_dict(exclude=exclude_data) for u in order_list],
            'totalCount': total,
            'TotalPageCount': math.ceil(int(total / limit))
        })

    except Exception as e:
        print("get orders error:", e)

    return jsonify({'code': 50001, 'message': "查询订单时发生错误"})


@a_order.route('', methods=['POST'])
@app_auth.login_required
def add_order():
    """
    @@@
    #### Args:
            {
                region: String(32)    #寄报地区
                province_city: String(127)    #地址
                address: String(127)    #详细住址
                postcode: String(8)    #邮编
                receiver: String(32)    #收货人
                phone: String(16)    #联系电话
                remark: String(127,)    #订单备注
                start_date: DateTime    #起始日期
                end_date: DateTime    #结束日期
                amount: SMALLINT(unsigned=True)    #报纸数量
                charge_standard: String(255)    #收费标准
                buyer: String(32)    #购买主体
                security_code: String(4)    #验证码
            }
    #### Returns::
            {'code': 20000, 'message': "订单添加成功"}
            {'code': 50001, 'message': "添加订单时发生错误"}
    """

    args = request.get_json()
    subscription_type = args.get("subscription_type")
    total_fee = args.get("total_fee")

    months = args.get("months")
    region = args.get("region")
    start_date = args.get("start_date")
    end_date = args.get("end_date")
    amount = args.get("amount")

    try:

        cal_months = calculate_month_difference(start_date, end_date)
        if cal_months != months:
            return jsonify({'code': 50002, 'message': "订单信息有误，请重新下单"})
        cal_total_fee = get_total_fee(subscription_type, region, cal_months, amount)
        print(total_fee, cal_total_fee)
        if total_fee != cal_total_fee:
            return jsonify({'code': 50002, 'message': "订单信息有误，请重新下单"})

        order = Order(user_id=g.user.id)
        set_field(order, args, exclude=exclude_data)
        db.session.add(order)
        db.session.commit()

        # user_opt.send({
        #     "operation": "添加订单",
        #     "method": "订单管理",
        #     "params": order.id,
        #     "user_id": g.user.id,
        #     "username": g.user.username
        # })

        return jsonify({'code': 20000, 'message': "订单添加成功", 'order': order.to_dict()})
    except Exception as e:
        db.session.rollback()
        print("add order error:", e)

    return jsonify({'code': 50001, 'message': "添加订单时发生错误"})


@a_order.route('create_wx_order', methods=['POST'])
@app_auth.login_required
def create_wx_order():
    """
    @@@
    #### Args:
            {
                booking_id: BIGINT(20    #对应定场记录id
                user_id: BIGINT(20    #用户
                body: String(64)    #商品描述
                order_no: String(64)    #微信订单号
                total_fee: DECIMAL(18    #付款金额
                purpose: TINYINT(4    #用途 0:订场 1:充值
                pay_type: TINYINT(4    #支付方式 0:线上⽀付 1:线下扫码⽀付 2:线下现⾦⽀付
                payer_id: BIGINT(20)    #支付用户
                user_create: BIGINT(20)    #创建用户
                status: TINYINT(unsigned=True)    #状态: 0:未支付 1:已支付 2:已取消 3:已失效
                remark: String(64)    #备注
            }
    #### Returns::
            {'code': 20000, 'message': "订单添加成功"}
            {'code': 50001, 'message': "添加订单时发生错误"}
    """

    args = request.get_json()
    order_id = args.get("order_id")

    try:
        order = Order.query.filter(Order.id == order_id).first()

        # 创建微信订单
        order_no, wxpay_params = create_wechat_order(order.body, int(order.total_fee * 100), g.user.open_id)
        # 临时测试
        # order_no, wxpay_params = create_wechat_order(order.body, int(0.01 * 100), g.user.open_id)
        print("?????? after created:", order_no, wxpay_params)
        order.order_no = order_no
        db.session.commit()

        return jsonify({'code': 20000, 'message': "订单创建成功", 'data': wxpay_params})
    except Exception as e:
        db.session.rollback()
        print("add order error:", e)

    return jsonify({'code': 50001, 'message': "添加订单时发生错误"})


def calculate_month_difference(start_date, end_date):
    # 解析日期
    _, start_month, _ = start_date.split('-')
    _, end_month, _ = end_date.split('-')

    # 转换为整数
    start_month = int(start_month)
    end_month = int(end_month)

    # 计算月份差
    month_diff = end_month - start_month + 1

    return month_diff
